#pragma once

#include"CruiseControl.h";
#include <sstream>;

namespace Cruising {

	using namespace System;
	using namespace System::ComponentModel;
	using namespace System::Collections;
	using namespace System::Windows::Forms;
	using namespace System::Data;
	using namespace System::Drawing;

	cruiseControl cc;
	//Sensor inputmailbox (data form naar cruisecontrol)
	mailBox *sensorInput;
	//Sensor output mailbox (data cruise control naar form)
	mailBox *sensorOutput;

	//sensor invoer naar cruise control toe
	SensorInvoer invoer;

	//sensor uitvoer naar form toe
	outputUitvoer uitvoer;

	//Variabelen om de vorige waarde te onthouden.
	//Als de nieuwe waarde anders is dan de vorige waarde hebben we een wijziging,
	//dus moeten we nieuwe data sturen naar de cruise control
	int remOud, gasOud, koppelingOud, snelheidOud;
	KnopType knopOud;


	/// <summary>
	/// Summary for Form1
	/// </summary>
	public ref class Form1 : public System::Windows::Forms::Form
	{
	public:
		Form1(void)
		{
			InitializeComponent();
			//
			//TODO: Add the constructor code here
			//
		}

	protected:
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		~Form1()
		{
			if (components)
			{
				delete components;
			}
		}
	private: System::Windows::Forms::Label^  label4;
	protected: 
	private: System::Windows::Forms::Label^  label3;
	private: System::Windows::Forms::Label^  label2;
	private: System::Windows::Forms::Label^  labelIngesteld;
	private: System::Windows::Forms::Label^  labelSnelheidNaBewerking;

	private: System::Windows::Forms::Button^  buttonActivatie;
	private: System::Windows::Forms::Label^  labelSnelheid;

	private: System::Windows::Forms::VScrollBar^  ScrollBarGas;
	private: System::Windows::Forms::VScrollBar^  ScrollBarRem;
	private: System::Windows::Forms::VScrollBar^  ScrollBarKoppeling;
	private: System::Windows::Forms::Button^  buttonSnelheidVerlagen;
	private: System::Windows::Forms::Button^  buttonSnelheidVerhogen;
	private: System::Windows::Forms::Button^  buttonPauze;
	private: System::Windows::Forms::Button^  buttonStartAuto;
	private: System::Windows::Forms::Label^  labelBijstellingSnelheid;
	private: System::Windows::Forms::Label^  label6;

	private: System::Windows::Forms::NumericUpDown^  SnelheidUpDown;


	private: System::Windows::Forms::Timer^  timerUpdate;
	private: System::Windows::Forms::Timer^  timerVerstuur;
	private: System::Windows::Forms::Label^  label1;
	private: System::Windows::Forms::Label^  label5;
	private: System::Windows::Forms::Label^  labelStatus;
	private: System::Windows::Forms::Label^  label7;
	private: System::ComponentModel::IContainer^  components;



	private:
		/// <summary>
		/// Required designer variable.
		/// </summary>


#pragma region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		void InitializeComponent(void)
		{
			this->components = (gcnew System::ComponentModel::Container());
			this->label4 = (gcnew System::Windows::Forms::Label());
			this->label3 = (gcnew System::Windows::Forms::Label());
			this->label2 = (gcnew System::Windows::Forms::Label());
			this->labelIngesteld = (gcnew System::Windows::Forms::Label());
			this->labelSnelheidNaBewerking = (gcnew System::Windows::Forms::Label());
			this->buttonActivatie = (gcnew System::Windows::Forms::Button());
			this->labelSnelheid = (gcnew System::Windows::Forms::Label());
			this->ScrollBarGas = (gcnew System::Windows::Forms::VScrollBar());
			this->ScrollBarRem = (gcnew System::Windows::Forms::VScrollBar());
			this->ScrollBarKoppeling = (gcnew System::Windows::Forms::VScrollBar());
			this->buttonSnelheidVerlagen = (gcnew System::Windows::Forms::Button());
			this->buttonSnelheidVerhogen = (gcnew System::Windows::Forms::Button());
			this->buttonPauze = (gcnew System::Windows::Forms::Button());
			this->buttonStartAuto = (gcnew System::Windows::Forms::Button());
			this->labelBijstellingSnelheid = (gcnew System::Windows::Forms::Label());
			this->label6 = (gcnew System::Windows::Forms::Label());
			this->SnelheidUpDown = (gcnew System::Windows::Forms::NumericUpDown());
			this->timerUpdate = (gcnew System::Windows::Forms::Timer(this->components));
			this->timerVerstuur = (gcnew System::Windows::Forms::Timer(this->components));
			this->label1 = (gcnew System::Windows::Forms::Label());
			this->label5 = (gcnew System::Windows::Forms::Label());
			this->labelStatus = (gcnew System::Windows::Forms::Label());
			this->label7 = (gcnew System::Windows::Forms::Label());
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->SnelheidUpDown))->BeginInit();
			this->SuspendLayout();
			// 
			// label4
			// 
			this->label4->AutoSize = true;
			this->label4->Location = System::Drawing::Point(428, 417);
			this->label4->Name = L"label4";
			this->label4->Size = System::Drawing::Size(26, 13);
			this->label4->TabIndex = 30;
			this->label4->Text = L"Gas";
			// 
			// label3
			// 
			this->label3->AutoSize = true;
			this->label3->Location = System::Drawing::Point(359, 417);
			this->label3->Name = L"label3";
			this->label3->Size = System::Drawing::Size(29, 13);
			this->label3->TabIndex = 29;
			this->label3->Text = L"Rem";
			// 
			// label2
			// 
			this->label2->AutoSize = true;
			this->label2->Location = System::Drawing::Point(276, 417);
			this->label2->Name = L"label2";
			this->label2->Size = System::Drawing::Size(54, 13);
			this->label2->TabIndex = 28;
			this->label2->Text = L"Koppeling";
			// 
			// labelIngesteld
			// 
			this->labelIngesteld->AutoSize = true;
			this->labelIngesteld->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 15, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, 
				static_cast<System::Byte>(0)));
			this->labelIngesteld->Location = System::Drawing::Point(228, 117);
			this->labelIngesteld->Name = L"labelIngesteld";
			this->labelIngesteld->Size = System::Drawing::Size(102, 25);
			this->labelIngesteld->TabIndex = 27;
			this->labelIngesteld->Text = L"Bijgesteld:";
			// 
			// labelSnelheidNaBewerking
			// 
			this->labelSnelheidNaBewerking->AutoSize = true;
			this->labelSnelheidNaBewerking->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 40, System::Drawing::FontStyle::Regular, 
				System::Drawing::GraphicsUnit::Point, static_cast<System::Byte>(0)));
			this->labelSnelheidNaBewerking->Location = System::Drawing::Point(321, 88);
			this->labelSnelheidNaBewerking->Name = L"labelSnelheidNaBewerking";
			this->labelSnelheidNaBewerking->Size = System::Drawing::Size(174, 63);
			this->labelSnelheidNaBewerking->TabIndex = 26;
			this->labelSnelheidNaBewerking->Text = L"0km/h";
			// 
			// buttonActivatie
			// 
			this->buttonActivatie->Location = System::Drawing::Point(12, 169);
			this->buttonActivatie->Name = L"buttonActivatie";
			this->buttonActivatie->Size = System::Drawing::Size(75, 23);
			this->buttonActivatie->TabIndex = 25;
			this->buttonActivatie->Text = L"Activatie";
			this->buttonActivatie->UseVisualStyleBackColor = true;
			this->buttonActivatie->Click += gcnew System::EventHandler(this, &Form1::buttonActivatie_Click);
			// 
			// labelSnelheid
			// 
			this->labelSnelheid->AutoSize = true;
			this->labelSnelheid->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 40, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, 
				static_cast<System::Byte>(0)));
			this->labelSnelheid->Location = System::Drawing::Point(4, 88);
			this->labelSnelheid->Name = L"labelSnelheid";
			this->labelSnelheid->Size = System::Drawing::Size(174, 63);
			this->labelSnelheid->TabIndex = 24;
			this->labelSnelheid->Text = L"0km/h";
			// 
			// ScrollBarGas
			// 
			this->ScrollBarGas->Location = System::Drawing::Point(431, 205);
			this->ScrollBarGas->Name = L"ScrollBarGas";
			this->ScrollBarGas->Size = System::Drawing::Size(19, 194);
			this->ScrollBarGas->TabIndex = 23;
			// 
			// ScrollBarRem
			// 
			this->ScrollBarRem->Location = System::Drawing::Point(362, 205);
			this->ScrollBarRem->Name = L"ScrollBarRem";
			this->ScrollBarRem->Size = System::Drawing::Size(19, 194);
			this->ScrollBarRem->TabIndex = 22;
			// 
			// ScrollBarKoppeling
			// 
			this->ScrollBarKoppeling->Location = System::Drawing::Point(292, 205);
			this->ScrollBarKoppeling->Name = L"ScrollBarKoppeling";
			this->ScrollBarKoppeling->Size = System::Drawing::Size(19, 194);
			this->ScrollBarKoppeling->TabIndex = 21;
			// 
			// buttonSnelheidVerlagen
			// 
			this->buttonSnelheidVerlagen->Location = System::Drawing::Point(212, 169);
			this->buttonSnelheidVerlagen->Name = L"buttonSnelheidVerlagen";
			this->buttonSnelheidVerlagen->Size = System::Drawing::Size(32, 23);
			this->buttonSnelheidVerlagen->TabIndex = 20;
			this->buttonSnelheidVerlagen->Text = L"-";
			this->buttonSnelheidVerlagen->UseVisualStyleBackColor = true;
			this->buttonSnelheidVerlagen->Click += gcnew System::EventHandler(this, &Form1::buttonSnelheidVerlagen_Click);
			// 
			// buttonSnelheidVerhogen
			// 
			this->buttonSnelheidVerhogen->Location = System::Drawing::Point(174, 169);
			this->buttonSnelheidVerhogen->Name = L"buttonSnelheidVerhogen";
			this->buttonSnelheidVerhogen->Size = System::Drawing::Size(32, 23);
			this->buttonSnelheidVerhogen->TabIndex = 19;
			this->buttonSnelheidVerhogen->Text = L"+";
			this->buttonSnelheidVerhogen->UseVisualStyleBackColor = true;
			this->buttonSnelheidVerhogen->Click += gcnew System::EventHandler(this, &Form1::buttonSnelheidVerhogen_Click);
			// 
			// buttonPauze
			// 
			this->buttonPauze->Location = System::Drawing::Point(93, 169);
			this->buttonPauze->Name = L"buttonPauze";
			this->buttonPauze->Size = System::Drawing::Size(75, 23);
			this->buttonPauze->TabIndex = 18;
			this->buttonPauze->Text = L"Pauze";
			this->buttonPauze->UseVisualStyleBackColor = true;
			this->buttonPauze->Click += gcnew System::EventHandler(this, &Form1::buttonPauze_Click);
			// 
			// buttonStartAuto
			// 
			this->buttonStartAuto->Location = System::Drawing::Point(12, 12);
			this->buttonStartAuto->Name = L"buttonStartAuto";
			this->buttonStartAuto->Size = System::Drawing::Size(75, 23);
			this->buttonStartAuto->TabIndex = 17;
			this->buttonStartAuto->Text = L"Start auto";
			this->buttonStartAuto->UseVisualStyleBackColor = true;
			this->buttonStartAuto->Click += gcnew System::EventHandler(this, &Form1::buttonStartAuto_Click);
			// 
			// labelBijstellingSnelheid
			// 
			this->labelBijstellingSnelheid->AutoSize = true;
			this->labelBijstellingSnelheid->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 40, System::Drawing::FontStyle::Regular, 
				System::Drawing::GraphicsUnit::Point, static_cast<System::Byte>(0)));
			this->labelBijstellingSnelheid->Location = System::Drawing::Point(321, 25);
			this->labelBijstellingSnelheid->Name = L"labelBijstellingSnelheid";
			this->labelBijstellingSnelheid->Size = System::Drawing::Size(174, 63);
			this->labelBijstellingSnelheid->TabIndex = 31;
			this->labelBijstellingSnelheid->Text = L"0km/h";
			// 
			// label6
			// 
			this->label6->AutoSize = true;
			this->label6->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 15, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, 
				static_cast<System::Byte>(0)));
			this->label6->Location = System::Drawing::Point(228, 54);
			this->label6->Name = L"label6";
			this->label6->Size = System::Drawing::Size(99, 25);
			this->label6->TabIndex = 32;
			this->label6->Text = L"Bijstelling:";
			// 
			// SnelheidUpDown
			// 
			this->SnelheidUpDown->Location = System::Drawing::Point(121, 240);
			this->SnelheidUpDown->Name = L"SnelheidUpDown";
			this->SnelheidUpDown->Size = System::Drawing::Size(120, 20);
			this->SnelheidUpDown->TabIndex = 34;
			// 
			// timerUpdate
			// 
			this->timerUpdate->Tick += gcnew System::EventHandler(this, &Form1::timerUpdate_Tick);
			// 
			// timerVerstuur
			// 
			this->timerVerstuur->Tick += gcnew System::EventHandler(this, &Form1::timerVerstuur_Tick);
			// 
			// label1
			// 
			this->label1->AutoSize = true;
			this->label1->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 15, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, 
				static_cast<System::Byte>(0)));
			this->label1->Location = System::Drawing::Point(12, 66);
			this->label1->Name = L"label1";
			this->label1->Size = System::Drawing::Size(95, 25);
			this->label1->TabIndex = 35;
			this->label1->Text = L"Snelheid:";
			// 
			// label5
			// 
			this->label5->AutoSize = true;
			this->label5->Location = System::Drawing::Point(15, 242);
			this->label5->Name = L"label5";
			this->label5->Size = System::Drawing::Size(100, 13);
			this->label5->TabIndex = 36;
			this->label5->Text = L"Wat is de snelheid\?";
			// 
			// labelStatus
			// 
			this->labelStatus->AutoSize = true;
			this->labelStatus->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 12, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, 
				static_cast<System::Byte>(0)));
			this->labelStatus->Location = System::Drawing::Point(58, 347);
			this->labelStatus->Name = L"labelStatus";
			this->labelStatus->Size = System::Drawing::Size(14, 20);
			this->labelStatus->TabIndex = 37;
			this->labelStatus->Text = L"-";
			// 
			// label7
			// 
			this->label7->AutoSize = true;
			this->label7->Location = System::Drawing::Point(12, 352);
			this->label7->Name = L"label7";
			this->label7->Size = System::Drawing::Size(40, 13);
			this->label7->TabIndex = 38;
			this->label7->Text = L"Status:";
			// 
			// Form1
			// 
			this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
			this->ClientSize = System::Drawing::Size(561, 449);
			this->Controls->Add(this->label7);
			this->Controls->Add(this->labelStatus);
			this->Controls->Add(this->label5);
			this->Controls->Add(this->label1);
			this->Controls->Add(this->SnelheidUpDown);
			this->Controls->Add(this->label6);
			this->Controls->Add(this->labelBijstellingSnelheid);
			this->Controls->Add(this->label4);
			this->Controls->Add(this->label3);
			this->Controls->Add(this->label2);
			this->Controls->Add(this->labelIngesteld);
			this->Controls->Add(this->labelSnelheidNaBewerking);
			this->Controls->Add(this->buttonActivatie);
			this->Controls->Add(this->labelSnelheid);
			this->Controls->Add(this->ScrollBarGas);
			this->Controls->Add(this->ScrollBarRem);
			this->Controls->Add(this->ScrollBarKoppeling);
			this->Controls->Add(this->buttonSnelheidVerlagen);
			this->Controls->Add(this->buttonSnelheidVerhogen);
			this->Controls->Add(this->buttonPauze);
			this->Controls->Add(this->buttonStartAuto);
			this->Name = L"Form1";
			this->Text = L"Form1";
			this->FormClosing += gcnew System::Windows::Forms::FormClosingEventHandler(this, &Form1::Form1_FormClosing);
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->SnelheidUpDown))->EndInit();
			this->ResumeLayout(false);
			this->PerformLayout();

		}
#pragma endregion


private: System::Void buttonStartAuto_Click(System::Object^  sender, System::EventArgs^  e) {
			//Nieuwe cruise control
			CruiseInit(&cc);
			//Sensor mailbox
			sensorInput = Get_sensorInput(&cc);
			//Output mailbox
			sensorOutput = Get_outputOut(&cc);			
			//Taak auto starten - starten
			create_task(cc.taak, autostart, &cc, sizeof(cruiseControl),0);

			//Zet alle waarden op 0 en op de values momenteel voorhanden op het form
			//De zogenoemde "nul-waarden" van de variabelen.
			invoer.snelheid = 0;
			invoer.gas=ScrollBarGas->Value;
			invoer.rem=ScrollBarRem->Value;
			invoer.koppeling=ScrollBarKoppeling->Value;
			invoer.knoppen = GeenKnop;
			remOud = 0;
			gasOud = 0;
			koppelingOud = 0;
			snelheidOud = 0;
			knopOud = GeenKnop;

			//Start de timer welke de data vanuit de cruise control leest en de 
			//elementen op het form aan past
			timerUpdate->Enabled = true;

			//Start de timer welke de data vanuit het form leest en deze naar de
			//cruise control stuurt
			timerVerstuur->Enabled = true;
		 }

private: System::Void buttonActivatie_Click(System::Object^  sender, System::EventArgs^  e) {
			 //Pas het knoptype aan
			 invoer.knoppen = AanuitKnop;
		 }

private: System::Void buttonPauze_Click(System::Object^  sender, System::EventArgs^  e) {
			 //Pas het knoptype aan
			 invoer.knoppen = PauzeKnop;
		 }

private: System::Void buttonSnelheidVerhogen_Click(System::Object^  sender, System::EventArgs^  e) {
			 //Pas het knoptype aan
			 invoer.knoppen = VersnellenKnop;
		 }

private: System::Void buttonSnelheidVerlagen_Click(System::Object^  sender, System::EventArgs^  e) {
			 //Pas het knoptype aan
			 invoer.knoppen = VertragenKnop;
		 }

private: System::Void Form1_FormClosing(System::Object^  sender, System::Windows::Forms::FormClosingEventArgs^  e) {
			 //Stop timers
			 timerUpdate->Enabled = false;
			 timerVerstuur->Enabled = false;
			 //Roep de methode CruiseDelete aan om alle geheugen, gebruikt 
			 //door de cruise control, op te ruimen
			 CruiseDelete(&cc);

			 //Verwijdert ook alle geheugen gebruikt door STD
			 Afsluiten();			 		
		 }
private: System::Void timerUpdate_Tick(System::Object^  sender, System::EventArgs^  e) {
			 //Gebruikt om verschil tussen huidige snelheid en ingestelde schnelheid
			 //te berekenen.
			 int verschil = 0;
			 
			 //Als de mailbox niet leeg is, dan haal de nieuwe data binnen.
			 if(isEmpty_mailBox(sensorOutput) == 0)
			 {
				get_mailBox(sensorOutput,&uitvoer);
				labelBijstellingSnelheid->Text = Convert::ToString(uitvoer.bijstellingSnelheid) + "km/h";			
			 }
			 
			 //Bekijk de status
			 switch(uitvoer.stat)
			 {
				 case(inactief):
					 labelStatus->Text = "Inactief";
				 break;
				 case(actief):
					 labelStatus->Text = "Actief";
				 break;
				 case(pauze):
					 labelStatus->Text = "Pauze";
				 break;
			 }

			 //Bereken het verschil
			 verschil = (Convert::ToInt32(SnelheidUpDown->Value)+(uitvoer.bijstellingSnelheid));
			 //Converteren naar string
			 System::String^ str = Convert::ToString(verschil);
			 //Pas label aan
			 labelSnelheidNaBewerking->Text = str + "km/h";	
		 }
private: System::Void timerVerstuur_Tick(System::Object^  sender, System::EventArgs^  e) {
			 //Haal stand van koppeling op
			 invoer.koppeling = ScrollBarKoppeling->Value;
			 //Haal stand van rem op
			 invoer.rem = ScrollBarRem->Value;
			 //Haal stand van gas op
			 invoer.gas = ScrollBarGas->Value;
			 //Haal de snelheid op
			 invoer.snelheid = Convert::ToInt32(SnelheidUpDown->Value);

			 //Als 1 (of meer) van het/de element(en) gewijzigd is/zijn dan gaan we 
			 //nieuwe data sturen. Dit functioneert dus als een soort event. 
			 //De cruise control krijgt alleen nieuwe data wanneer dit nodig is.
			 if(invoer.koppeling != koppelingOud || invoer.rem != remOud || invoer.gas != gasOud || invoer.snelheid != snelheidOud || invoer.knoppen != knopOud)
			 {
				 //We gaan nu de oude waarden zetten op de waarden die we momenteel hebben
				 //Op deze manier zijn deze huidige waarden dan de oude waarden voor een
				 //volgende check op de data.
				 koppelingOud = invoer.koppeling;
				 remOud = invoer.rem;
				 gasOud = invoer.gas;
				 snelheidOud = invoer.snelheid;
				 knopOud = invoer.knoppen;

				 //Converteren naar string
				 System::String^ str = Convert::ToString(SnelheidUpDown->Value);
				 //Label aanpassen
				 labelSnelheid->Text = str + "km/h";
				 //De data in de mailbox droppen
				 put_mailBox(sensorInput,&invoer);
			 }
			 //Knoptype herstellen naar GeenKnop.
			 //We willen alleen een knop meesturen als we ook daadwerkelijk een knop
			 //ingedrukt hebben
			 invoer.knoppen = GeenKnop;
		 }
};
}
